library(tidyverse)
library(eph)
library(spatstat)
options(scipen = 9999)
options(dplyr.summarise.inform = FALSE)

Introducción

En la clase de hoy vamos a explorar nuevas formas de procesar una base de datos y visualizar nuestros resultados.

En particular, vamos a introducir el paquete plotly para generar visualizaciones interactivas.

Por último, vamos a trabajar con funciones e iteraciones para escalar nuestra capacidad de análisis de datos y presentación de resultados.

Visualización interactiva

La visualización interactiva va a permitir que los usuarios de nuestras visualizaciones puedan explorar nuestros resultados con mayor libertad. Es decir, van a permitir que cada usuario pueda analizar con mayor detalle lo que más le interesa.

Vamos a volver a trabajar con la base de EPH para encontrar la brecha salarial entre varones y mujeres para cada sector productivo, y luego vamos a graficarlo interactivamente.

base <- eph::get_microdata(year = 2019, 
                            trimester = 1,
                            type = "individual", 
                            destfile = "bases_fuentes/eph_2019_T1.rds")  %>% 
  organize_caes()%>%  #recodifica la variable que indica el sector de la ocupación
  select(ESTADO,"SEXO" = CH04, "Ing_Ocup_Principal"= P21, PONDIIO,caes_eph_label, "Horas" = PP3E_TOT) %>% 
  
  mutate(ESTADO = case_when(ESTADO == 1 ~ "Ocupado",
                            ESTADO == 2 ~ "Desocupado",
                            ESTADO == 3 ~ "Inactivo",
                            ESTADO == 4 ~ "Menor de 10 años"),
         SEXO = case_when(SEXO == 1 ~ "Varones",
                          SEXO == 2 ~ "Mujeres")) %>% 
  filter(Ing_Ocup_Principal != -9) %>%  #valor de no respuesta
  filter(ESTADO == "Ocupado")

Calculamos el ingreso medio de los trabajadores de cada sexo y sector, y luego la brecha. También vamos a tener en cuenta en qué sectores las mujeres tienen una participación mayor.

# Aclaración: el ponderador para la variable de ingreso de la ocupación
# proncipal es PONDIIO

ingresos <- base %>%
    filter(Ing_Ocup_Principal > 0) %>%
    group_by(SEXO, caes_eph_label) %>%
    summarise(Ingreso_medio = weighted.mean(Ing_Ocup_Principal, PONDIIO, na.rm = T)) %>%
    pivot_wider(id_cols = caes_eph_label, names_from = SEXO, values_from = Ingreso_medio) %>%
    mutate(Brecha = ((Varones - Mujeres)/Varones))

participacion <- base %>%
    group_by(SEXO, caes_eph_label) %>%
    summarise(Casos = n()) %>%
    ungroup() %>%
    group_by(caes_eph_label) %>%
    mutate(Total = sum(Casos), Prop = (Casos/Total) * 100) %>%
    filter(SEXO == "Mujeres") %>%
    select(caes_eph_label, Prop)

ingresos <- ingresos %>%
    left_join(., participacion, by = "caes_eph_label")

ingresos
## # A tibble: 14 x 5
##    caes_eph_label                                  Mujeres Varones  Brecha  Prop
##    <fct>                                             <dbl>   <dbl>   <dbl> <dbl>
##  1 Actividades primarias                            26607.  38218.  0.304  10.8 
##  2 Industria manufacturera                          15351.  23005.  0.333  30.5 
##  3 Construccion                                     17316.  15654. -0.106   3.05
##  4 Comercio                                         14916.  20068.  0.257  40.3 
##  5 Hoteles y restaurantes                           11952.  15263.  0.217  49.6 
##  6 Transporte, almacenamiento y comunicaciones      24106.  26564.  0.0925 14.3 
##  7 Servicios financieros, de alquiler y empresari~  23430.  27491.  0.148  40.8 
##  8 Administracion publica, defensa y seguridad so~  25803.  27890.  0.0748 43.9 
##  9 Ensenanza                                        19573.  22295.  0.122  74.4 
## 10 Servicios sociales y de salud                    24354.  34723.  0.299  68.0 
## 11 Servicio domestico                                6844.   5779. -0.184  96.1 
## 12 Otros servicios comunitarios, sociales y perso~  10810.  20931.  0.484  44.7 
## 13 Otras ramas                                      29610.  26477. -0.118  13.5 
## 14 Actividades no bien especificadas                23731.  28258.  0.160  23.9

plotly

Para graficar nuestros resultados, vamos a recurrir al paquete plotly. Este paquete nos ayuda a crear gráficos interactivos (y puede utilizarse en combinación con ggplot para transformar un gráfico no interactivo en un gráfico interactivo).

library(plotly)

En nuestro gráfico, vamos a graficar el ingreso medio de cada sector productivo para trabajadores de cada sexo, coloreando cada burbuja de acuerdo con la magnitud de la brecha, y determinando el tamaño de la burbuja según la proporción de trabajadoras mujeres en el sector.

plot_ly(ingresos, x = ~Mujeres, y = ~Varones, 
        color = ~Brecha, colors = 'Spectral',
        type = 'scatter', mode = 'markers',  marker = list(size = ~Prop, opacity = 0.9),
        
        hoverinfo = 'text',
        text = ~paste(caes_eph_label, '<br>Mujeres:', paste0("$",round(Mujeres,1)), '<br>Varones:', paste0("$",round(Varones,1)), '<br>Brecha:', paste0(round(Brecha*100,1), "%"), '<br>Proporción de trabajadoras mujeres:', paste0(round(Prop,1), "%"))
        
        ) %>% 
       layout(title = 'Ingreso medio y brecha salarial por sector productivo',
         xaxis = list(showgrid = FALSE),
         yaxis = list(showgrid = FALSE))

Prueben pasar el mouse por encima del gráfico, moverlo, hacer zoom, etc.

¿Qué análisis podemos hacer de la información representada?

Iteración y funciones

La iteración y las funciones nos van a permitir reducir la duplicación en el código (copiar y pegar las mismas instrucciones).

¿Por qué reducir la duplicación?

  • Es más fácil entender tu código (para vos en otro momento, o para un tercero).

  • Es más simple realizar cambios y encontrar errores.

Además, van a potenciar nuestro trabajo con R, permitiéndonos escalar la cantidad de procesamientos y visualizaciones que podemos obtener a partir del análisis de una base de datos en muy poco tiempo.

Iteraciones

La iteración es una herramienta para repetir la misma tarea con múltiples inputs (variables, conjuntos de datos, etc.).

Un loop es una estructura de código que nos permite aplicar iterativamente un mismo conjunto de comandos, variando el valor de una variable. Su estructura general es la siguiente:

for (variable in vector) {
    # Operaciones
}

El nombre que definamos para la variable debe ser el mismo que utilicemos para realizar las operaciones dentro del loop, pero puede ser cualquiera (x,i,planta,supercalifragil, etc).

Por ejemplo:

for (x in 1:5) {
    print(x * x)
}
## [1] 1
## [1] 4
## [1] 9
## [1] 16
## [1] 25

Lo que hizo el código fue crear una variable x, que fue tomando los valores 1, 2, 3, 4 y 5, y en cada caso multiplicándose por sí misma.

En nuestro loop pueden intervenir también objetos que hayamos definido previamente.

Por ejemplo:

b <- 10

for (x in 1:5) {
    print(x + b)
}
## [1] 11
## [1] 12
## [1] 13
## [1] 14
## [1] 15

Una herramienta que vamos a utilizar mucho es la función seq(), que permite generar una secuencia de números (que vamos a utilizar para iterar). Por default, si ingresamos un único número como argumento, genera una secuencia desde 1 hasta ese número.

seq(3)
## [1] 1 2 3
for (i in (seq(3))) {
    print(i)
}
## [1] 1
## [1] 2
## [1] 3

¿Cuándo podríamos usar esto? En operaciones de subsetting o slicing

# defino el vector
vec <- c("a", "b", "c")

# ¿cuántos elementos tiene?
length(vec)
## [1] 3
# Convierto cada elemento al mismo elemento en mayúscula
for (letra in (seq(length(vec)))) {
    vec[letra] <- toupper(vec[letra])
}

# ¿Cómo quedó?
vec
## [1] "A" "B" "C"

¿Qué pasó? Nuestro loop fue avanzando sobre los elementos de vec, reemplazándolos por el mismo valor en mayúscula. Por ejemplo, al vec[1] = “a”, lo transformó en “A”.

Aplicación sobre una base de datos

Veamos cómo puede ser útil para un procesamiento.

Si tenemos una base de datos con información sobre distintos tipos de población, podemos querer generar una medida resumen para cada segmento de la población.

Por ejemplo, supongamos que queremos llevar a cabo un análisis más detallado de la distribución de los ingresos por sexo para cada rama de actividad:

vector_valores <- unique(base$caes_eph_label)

# En esta lista vamos a guardar nuestros resultados
resultados <- list()

for (valor in (seq(length(vector_valores)))) {

    tabla_resumen <- base %>%
        filter(caes_eph_label == vector_valores[valor]) %>%
        filter(Ing_Ocup_Principal > 0) %>%
        group_by(SEXO) %>%
        summarise(sector = unique(caes_eph_label), max_ing = max(Ing_Ocup_Principal,
            na.rm = T), min_ing = min(Ing_Ocup_Principal, na.rm = T), media_ing = weighted.mean(Ing_Ocup_Principal,
            PONDIIO, na.rm = T), mediana_ing = weighted.median(Ing_Ocup_Principal,
            PONDIIO, na.rm = T))

    resultados[[valor]] <- tabla_resumen

}

# Veamos una de las tablas que generamos:

resultados[[3]]
## # A tibble: 2 x 6
##   SEXO    sector                           max_ing min_ing media_ing mediana_ing
##   <chr>   <fct>                              <int>   <int>     <dbl>       <dbl>
## 1 Mujeres Servicios financieros, de alqui~  100000     450    23430.       20000
## 2 Varones Servicios financieros, de alqui~  300000     300    27491.       22000

También podemos presentar nuestros resultados de una manera más amigable con quien está leyendo, o listo para copiar e incluir en un informe:

for (valor in (seq(length(vector_valores)))) {

    print(paste0("Para el sector ", unique(resultados[[valor]]$sector), ", el ingreso máximo alcanzado por un varón fue de $",
        resultados[[valor]]$max_ing[resultados[[valor]]$SEXO == "Varones"], ". Para las mujeres, por otro lado, fue de $",
        resultados[[valor]]$max_ing[resultados[[valor]]$SEXO == "Mujeres"]))


}
## [1] "Para el sector Actividades primarias, el ingreso máximo alcanzado por un varón fue de $250000. Para las mujeres, por otro lado, fue de $80000"
## [1] "Para el sector Construccion, el ingreso máximo alcanzado por un varón fue de $200000. Para las mujeres, por otro lado, fue de $75000"
## [1] "Para el sector Servicios financieros, de alquiler y empresariales, el ingreso máximo alcanzado por un varón fue de $300000. Para las mujeres, por otro lado, fue de $100000"
## [1] "Para el sector Transporte, almacenamiento y comunicaciones, el ingreso máximo alcanzado por un varón fue de $290000. Para las mujeres, por otro lado, fue de $70000"
## [1] "Para el sector Ensenanza, el ingreso máximo alcanzado por un varón fue de $100000. Para las mujeres, por otro lado, fue de $70000"
## [1] "Para el sector Administracion publica, defensa y seguridad social, el ingreso máximo alcanzado por un varón fue de $150000. Para las mujeres, por otro lado, fue de $200000"
## [1] "Para el sector Comercio, el ingreso máximo alcanzado por un varón fue de $300000. Para las mujeres, por otro lado, fue de $100000"
## [1] "Para el sector Servicio domestico, el ingreso máximo alcanzado por un varón fue de $15000. Para las mujeres, por otro lado, fue de $40500"
## [1] "Para el sector Industria manufacturera, el ingreso máximo alcanzado por un varón fue de $200000. Para las mujeres, por otro lado, fue de $200000"
## [1] "Para el sector Hoteles y restaurantes, el ingreso máximo alcanzado por un varón fue de $60000. Para las mujeres, por otro lado, fue de $35000"
## [1] "Para el sector Otros servicios comunitarios, sociales y personales, el ingreso máximo alcanzado por un varón fue de $250000. Para las mujeres, por otro lado, fue de $80000"
## [1] "Para el sector Servicios sociales y de salud, el ingreso máximo alcanzado por un varón fue de $390000. Para las mujeres, por otro lado, fue de $150000"
## [1] "Para el sector Otras ramas, el ingreso máximo alcanzado por un varón fue de $70000. Para las mujeres, por otro lado, fue de $60000"
## [1] "Para el sector Actividades no bien especificadas, el ingreso máximo alcanzado por un varón fue de $100000. Para las mujeres, por otro lado, fue de $80000"

Funciones

Retomamos lo introducido en la clase 2: la función es una forma de encapsular una serie de operaciones a las que vayamos a recurrir más de una vez, esta es su estructura general:

fun_ej <- function(argumentos) {
    # [se hace algún cómputo]
}

En este caso, vamos a utilizar esta herramienta -en conjunto con la iteración- para generar una serie de gráficos donde se visualice la distribución de los ingresos de las mujeres y los varones que se desempeñan en cada sector productivo de acuerdo con las horas que trabajan por semana.

Primero, vamos a generar los datos que vamos a graficar:

vector_valores <- unique(base$caes_eph_label)

# En esta lista vamos a guardar nuestros resultados
datos_graf <- list()

for (valor in (seq(length(vector_valores)))) {

    tabla_resumen <- base %>%
        filter(caes_eph_label == vector_valores[valor]) %>%
        filter(Ing_Ocup_Principal > 0) %>%
        filter(Horas > 0) %>%
        filter(Horas != 999) %>%
        group_by(SEXO, Ing_Ocup_Principal, Horas) %>%
        summarise(Casos = sum(PONDIIO, na.rm = T), sector = unique(caes_eph_label))

    datos_graf[[valor]] <- tabla_resumen

}

Luego, creamos nuestra función que grafica la información de una tabla:

crear_grafico = function(tabla) {

    ggplot(tabla, aes(x = Horas, y = Ing_Ocup_Principal, size = Casos, color = SEXO)) +
        geom_point(alpha = 0.4) + theme_minimal() + scale_color_manual(values = c("deeppink4",
        "mediumseagreen")) + scale_size_continuous(range = c(2, 15)) + scale_y_continuous(labels = function(x) paste0("$",
        x)) + facet_wrap(~SEXO, scales = "fixed", nrow = 1) + labs(title = unique(tabla$sector),
        y = "Ingreso de la ocupación principal", x = "Horas semanales trabajadas",
        color = "Sexo") + theme(legend.position = "bottom") + ggsave(paste0("clase6/graficos/",
        tolower(str_replace_all(unique(tabla$sector), " ", "_")), ".png"))

}

Finalmente, la aplicamos de forma iterativa:

for (i in seq(length(datos_graf))) {

    crear_grafico(datos_graf[[i]])

}

Los resultados de nuestro prcesamiento están guardados en la carpeta graficos de la clase 6.

Algunos ejercicios para empezar a practicar